package cn.edu.cug.cs.gtl.plugins.catalog.tree;

import cn.edu.cug.cs.gtl.apis.ui.AbstractApplication;
import cn.edu.cug.cs.gtl.apis.ui.actions.AbstractAction;
import cn.edu.cug.cs.gtl.apis.ui.datake.DatakeApp;
import cn.edu.cug.cs.gtl.apis.ui.datake.DatakeFrame;
import cn.edu.cug.cs.gtl.apis.ui.datake.catalogtree.CatalogTree;
import cn.edu.cug.cs.gtl.apis.ui.imageuis.ImageUIApp;
import cn.edu.cug.cs.gtl.apis.ui.mapuis.Map2dUIApp;
import cn.edu.cug.cs.gtl.apis.ui.seriesuis.SeriesUIApp;
import cn.edu.cug.cs.gtl.apis.ui.table.TablePanel;
import cn.edu.cug.cs.gtl.apis.ui.tableuis.TableUIApp;
import cn.edu.cug.cs.gtl.apis.ui.textuis.TextUIApp;
import cn.edu.cug.cs.gtl.apis.ui.tree.TreeNodeData;
import cn.edu.cug.cs.gtl.chart.Chart;
import cn.edu.cug.cs.gtl.chart.ChartFactory;
import cn.edu.cug.cs.gtl.chart.data.xy.XYDataset;
import cn.edu.cug.cs.gtl.chart.data.xy.XYSeries;
import cn.edu.cug.cs.gtl.chart.data.xy.XYSeriesCollection;
import cn.edu.cug.cs.gtl.chart.swing.ChartPanel;
import cn.edu.cug.cs.gtl.common.Pair;
import cn.edu.cug.cs.gtl.plugins.catalog.utils.HdfsFileUtils;
import cn.edu.cug.cs.gtl.protos.DataItem;
import cn.edu.cug.cs.gtl.series.common.Series;
import cn.edu.cug.cs.gtl.series.ml.SeriesGroup;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.List;

public class FileDoubleClickActions extends AbstractAction {


    @Override
    public void initialize(AbstractApplication theApp) {
        this.theApp = theApp;

        // 获取 CatalogTree
        CatalogTree catalogTree = (CatalogTree) getDataFrame().getCatalogPanel().getTreeComponent();

        // 添加双击监听器
        catalogTree.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    actionPerformed(new ActionEvent(catalogTree, ActionEvent.ACTION_PERFORMED, "Double Click"));
                }
            }
        });
    }

    public static FSDataInputStream getFSDataInputStream(String hdfsFilePath) {
        Configuration conf = new Configuration();
        conf.set("dfs.client.use.datanode.hostname", "true");

        URI uri = null;
        try {
            uri = new URI(hdfsFilePath);
            FileSystem fs = FileSystem.get(uri, conf);
            Path path = new Path(hdfsFilePath);
            return fs.open(path);
        } catch (URISyntaxException | IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        CatalogTree tree = (CatalogTree) e.getSource();
        TreePath selectionPath = tree.getSelectionPath();

        if (selectionPath != null) {
            //获取当前选中节点
            DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selectionPath.getLastPathComponent();
            TreeNodeData treeNodeData = (TreeNodeData) selectedNode.getUserObject();
            Object obj = treeNodeData.getRefObject();

            if (obj instanceof DataItem) {
                DataItem dataItem = (DataItem) obj;

                //对tsv文件进行处理
                if (dataItem.getFormat().equals(".tsv")) {
                    timeSeriesDataAction(dataItem);
                } else if (dataItem.getFormat().equals(".txt")) {
                    textDataAction(dataItem);
                } else if (dataItem.getFormat().equals(".doc")) {
                    docDataAction(dataItem);
                } else if (dataItem.getFormat().equals("docx")) {
                    docxDataAction(dataItem);
                }

                //获取该文件在HDFS中的路径
                String hdfsFilePath = dataItem.getKey().getFileKey().getUrl();
                FSDataInputStream fis = getFSDataInputStream(hdfsFilePath);
                System.err.println(hdfsFilePath);

                String format = dataItem.getFormat();
                switch (format) {
                    //对表格类型文件进行处理
                    case ".csv":
                        try {
                            this.getDatakeApp().getTableUIApp().redrawCsvUI(fis);
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }
                        break;
                    case ".xlsx":
                    case ".xls":
                        try {
                            this.getDatakeApp().getTableUIApp().redrawXlsxUI(fis, format);
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }
                        break;

                    //对shp类型文件进行处理
                    case ".shp":
                        try {
                            this.getDatakeApp().getMapUIApp().redrawShpUI(fis);
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }
                        break;

                    //对图片类型文件进行处理
                    case ".jpg":
                    case ".png":
                        try {
                            this.getDatakeApp().getImageUIApp().redRawJpgUI(fis,format);
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }
                        break;
                }
            }

        }
    }

    public void timeSeriesDataAction(DataItem dataItem) {
        //获取该文件在HDFS中的路径
        String filePath = dataItem.getKey().getFileKey().getUrl();

        //使用 SwingWorker 执行后台任务
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                try {
                    // 在后台下载文件
                    //java.nio.file.Path localTempFilePath = HdfsFileUtils.downloadFile(filePath);

                    // 读取数据并生成图表
                    SeriesGroup seriesGroup = readUCRArchiveData(filePath);
                    XYDataset<String> dataset = generateDataset(seriesGroup);
                    Chart chart = createChart(dataset);

                    // 在 Event Dispatch Thread（EDT） 上更新 Swing UI
                    SwingUtilities.invokeLater(() -> {
                        // 在 EDT 上创建并显示 UI
                        ChartPanel chartPanel = new ChartPanel(chart);
                        addChartPanelToSeriesUIApp(chartPanel);
                    });

                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
                return null;
            }
        };

        // 启动 SwingWorker
        worker.execute();
    }


    public void addChartPanelToSeriesUIApp(ChartPanel chartPanel) {
        // 获取 SeriesUIApp
        SeriesUIApp seriesUIApp = (SeriesUIApp) getDatakeApp().getSeriesUIApp();

        // 将 ChartPanel 加到 SeriesUIApp 的 UI 中
        JComponent ui = seriesUIApp.initializeUI();

        // 更新 SeriesUIApp 的 UI
        seriesUIApp.updateUI(chartPanel);
    }


    public SeriesGroup readUCRArchiveData(String path) throws Exception {
//        UCRArchiveDatabase database = new UCRArchiveDatabase(path);
//        List<String> names = database.getCatalogNames();
//        SeriesCatalog catalog = database.getCatalog(6);
//        List<String> groupNames = catalog.getGroupNames();
//        SeriesGroup group = catalog.getGroup(0);
//        return group;

        SeriesGroup seriesGroup = new SeriesGroup(path.substring(path.lastIndexOf('/') + 1));
        List<Pair<String, double[]>> ls = HdfsFileUtils.readTSVFileFromHDFS(path);
        Iterator var10 = ls.iterator();

        Pair p;
        while (var10.hasNext()) {
            p = (Pair) var10.next();
            seriesGroup.add(new cn.edu.cug.cs.gtl.series.ml.Series((double[]) p.second(), (String) p.first()));
        }
        return seriesGroup;
    }

    public XYDataset<String> generateDataset(SeriesGroup g) {
//        XYSeries<String> series1 = new XYSeries<>("Series 1");
//        for(int i=0;i<1000;++i){
//            series1.add(i*1.0, Math.sin(i*1.0*Math.PI/360));
//        }
//        XYDataset<String> dataset = new XYSeriesCollection<>(series1);

        XYSeriesCollection<String> dataset = new XYSeriesCollection<String>();
        int n = Math.min(10, g.size());
        for (int j = 0; j < n; ++j) {
            Series s = g.getSeries(j);

            XYSeries<String> series1 = new XYSeries<>(g.getName() + "_" + Integer.valueOf(j).toString());
            double[] xx = s.getDataX();
            double[] yy = s.getDataY();
            int m = Math.min(xx.length, yy.length);
            for (int i = 0; i < m; ++i) {
                series1.add(xx[i], yy[i]);
            }
            dataset.addSeries(series1);
        }
        return dataset;
    }


    public Chart createChart(XYDataset<String> dataset) {
        return ChartFactory.createXYLineChart("XY Line Chart", "Time", "Value", dataset);
    }

    public void textDataAction(DataItem dataItem) {
        //获取该文件在HDFS中的路径
        String filePath = dataItem.getKey().getFileKey().getUrl();

        //使用 SwingWorker 执行后台任务
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                try {
                    // 创建 RSyntaxTextArea
                    RSyntaxTextArea textArea = new RSyntaxTextArea(20, 60);
                    textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE); // 不进行语法高亮
                    textArea.setCodeFoldingEnabled(true);
                    // 设置背景色
                    textArea.setBackground(new Color(60, 63, 65)); // 这是 IntelliJ IDEA 的默认背景色
                    // 设置字体颜色
                    textArea.setForeground(new Color(187, 187, 187)); // 这是 IntelliJ IDEA 的默认字体颜色
                    // 设置选择文本的背景色
                    textArea.setSelectionColor(new Color(104, 104, 104)); // 这是 IntelliJ IDEA 的默认选择文本背景色
                    // 设置选择文本的字体颜色
                    textArea.setSelectedTextColor(new Color(255, 255, 255)); // 这是 IntelliJ IDEA 的默认选择文本字体颜色
                    // 设置光标的颜色
                    textArea.setCaretColor(new Color(255, 255, 255)); // 这是 IntelliJ IDEA 的默认光标颜色

                    // 创建 RTextScrollPane，将 RSyntaxTextArea 放入滚动窗格中
                    RTextScrollPane scrollPane = new RTextScrollPane(textArea);

                    // 增加字体大小的快捷键（Ctrl+滚轮上）
                    textArea.addMouseWheelListener(new MouseWheelListener() {
                        @Override
                        public void mouseWheelMoved(MouseWheelEvent e) {
                            if (e.isControlDown()) {
                                adjustFontSize(textArea, e.getWheelRotation());
                                e.consume();
                            }
                        }
                    });

                    // 快捷键监听器，Ctrl+加号放大，Ctrl+减号缩小
                    textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, InputEvent.CTRL_DOWN_MASK), "increaseFontSize");
                    textArea.getActionMap().put("increaseFontSize", new javax.swing.AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            adjustFontSize(textArea, 1);
                        }
                    });

                    textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK), "decreaseFontSize");
                    textArea.getActionMap().put("decreaseFontSize", new javax.swing.AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            adjustFontSize(textArea, -1);
                        }
                    });

                    // 读取数据
                    String content = HdfsFileUtils.readTextFileFromHDFS(filePath);

                    // 在 RSyntaxTextArea 中显示内容
                    textArea.setText(content);

                    // 在 Event Dispatch Thread（EDT） 上更新 Swing UI
                    SwingUtilities.invokeLater(() -> {
                        // 在 EDT 上创建并显示 UI
                        addPanelToTextUIApp(scrollPane);
                    });

                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
                return null;
            }
        };

        // 启动 SwingWorker
        worker.execute();
    }

    /**
     * 调整字体大小
     *
     * @param textArea
     * @param delta
     */
    public static void adjustFontSize(RSyntaxTextArea textArea, int delta) {
        Font currentFont = textArea.getFont();
        int currentSize = currentFont.getSize();
        Font newFont = currentFont.deriveFont((float) currentSize + delta);
        textArea.setFont(newFont);
    }

    public void addPanelToTextUIApp(RTextScrollPane scrollPane) {
        // 获取 TextUIApp
        TextUIApp textUIApp = (TextUIApp) getDatakeApp().getTextUIApp();

        // 更新 TextUIApp 的 UI
        textUIApp.updateUI(scrollPane);
    }

    private void docDataAction(DataItem dataItem) {
        //获取该文件在HDFS中的路径
        String filePath = dataItem.getKey().getFileKey().getUrl();

        //使用 SwingWorker 执行后台任务
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                try {
                    // 创建 RSyntaxTextArea
                    RSyntaxTextArea textArea = new RSyntaxTextArea(20, 60);
                    textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE); // 不进行语法高亮
                    textArea.setCodeFoldingEnabled(true);
                    // 设置背景色
                    textArea.setBackground(new Color(60, 63, 65)); // 这是 IntelliJ IDEA 的默认背景色
                    // 设置字体颜色
                    textArea.setForeground(new Color(187, 187, 187)); // 这是 IntelliJ IDEA 的默认字体颜色
                    // 设置选择文本的背景色
                    textArea.setSelectionColor(new Color(104, 104, 104)); // 这是 IntelliJ IDEA 的默认选择文本背景色
                    // 设置选择文本的字体颜色
                    textArea.setSelectedTextColor(new Color(255, 255, 255)); // 这是 IntelliJ IDEA 的默认选择文本字体颜色
                    // 设置光标的颜色
                    textArea.setCaretColor(new Color(255, 255, 255)); // 这是 IntelliJ IDEA 的默认光标颜色

                    // 创建 RTextScrollPane，将 RSyntaxTextArea 放入滚动窗格中
                    RTextScrollPane scrollPane = new RTextScrollPane(textArea);

                    // 增加字体大小的快捷键（Ctrl+滚轮上）
                    textArea.addMouseWheelListener(new MouseWheelListener() {
                        @Override
                        public void mouseWheelMoved(MouseWheelEvent e) {
                            if (e.isControlDown()) {
                                adjustFontSize(textArea, e.getWheelRotation());
                                e.consume();
                            }
                        }
                    });

                    // 快捷键监听器，Ctrl+加号放大，Ctrl+减号缩小
                    textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, InputEvent.CTRL_DOWN_MASK), "increaseFontSize");
                    textArea.getActionMap().put("increaseFontSize", new javax.swing.AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            adjustFontSize(textArea, 1);
                        }
                    });

                    textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK), "decreaseFontSize");
                    textArea.getActionMap().put("decreaseFontSize", new javax.swing.AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            adjustFontSize(textArea, -1);
                        }
                    });

                    // 读取数据
                    String content = HdfsFileUtils.readDocFileFromHDFS(filePath);

                    // 在 RSyntaxTextArea 中显示内容
                    textArea.setText(content);

                    // 在 Event Dispatch Thread（EDT） 上更新 Swing UI
                    SwingUtilities.invokeLater(() -> {
                        // 在 EDT 上创建并显示 UI
                        addPanelToTextUIApp(scrollPane);
                    });

                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
                return null;
            }
        };

        // 启动 SwingWorker
        worker.execute();
    }

    private void docxDataAction(DataItem dataItem) {
        //获取该文件在HDFS中的路径
        String filePath = dataItem.getKey().getFileKey().getUrl();

        //使用 SwingWorker 执行后台任务
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                try {
                    // 创建 RSyntaxTextArea
                    RSyntaxTextArea textArea = new RSyntaxTextArea(20, 60);
                    textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE); // 不进行语法高亮
                    textArea.setCodeFoldingEnabled(true);
                    // 设置背景色
                    textArea.setBackground(new Color(60, 63, 65)); // 这是 IntelliJ IDEA 的默认背景色
                    // 设置字体颜色
                    textArea.setForeground(new Color(187, 187, 187)); // 这是 IntelliJ IDEA 的默认字体颜色
                    // 设置选择文本的背景色
                    textArea.setSelectionColor(new Color(104, 104, 104)); // 这是 IntelliJ IDEA 的默认选择文本背景色
                    // 设置选择文本的字体颜色
                    textArea.setSelectedTextColor(new Color(255, 255, 255)); // 这是 IntelliJ IDEA 的默认选择文本字体颜色
                    // 设置光标的颜色
                    textArea.setCaretColor(new Color(255, 255, 255)); // 这是 IntelliJ IDEA 的默认光标颜色

                    // 创建 RTextScrollPane，将 RSyntaxTextArea 放入滚动窗格中
                    RTextScrollPane scrollPane = new RTextScrollPane(textArea);

                    // 增加字体大小的快捷键（Ctrl+滚轮上）
                    textArea.addMouseWheelListener(new MouseWheelListener() {
                        @Override
                        public void mouseWheelMoved(MouseWheelEvent e) {
                            if (e.isControlDown()) {
                                adjustFontSize(textArea, e.getWheelRotation());
                                e.consume();
                            }
                        }
                    });

                    // 快捷键监听器，Ctrl+加号放大，Ctrl+减号缩小
                    textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, InputEvent.CTRL_DOWN_MASK), "increaseFontSize");
                    textArea.getActionMap().put("increaseFontSize", new javax.swing.AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            adjustFontSize(textArea, 1);
                        }
                    });

                    textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK), "decreaseFontSize");
                    textArea.getActionMap().put("decreaseFontSize", new javax.swing.AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            adjustFontSize(textArea, -1);
                        }
                    });

                    // 读取数据
                    String content = HdfsFileUtils.readDocFileFromHDFS(filePath);

                    // 在 RSyntaxTextArea 中显示内容
                    textArea.setText(content);

                    // 在 Event Dispatch Thread（EDT） 上更新 Swing UI
                    SwingUtilities.invokeLater(() -> {
                        // 在 EDT 上创建并显示 UI
                        addPanelToTextUIApp(scrollPane);
                    });

                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
                return null;
            }
        };

        // 启动 SwingWorker
        worker.execute();
    }

    public DatakeApp getDatakeApp() {
        return (DatakeApp) theApp;
    }

    public DatakeFrame getDataFrame() {
        return (DatakeFrame) (theApp.getMainFrame());
    }
}
